﻿using System;
using System.Threading;
using System.Web.Mvc;
using Turquoise.Business.Abstract;
using Turquoise.Business.Options;
using Turquoise.Core.Entities;
using Turquoise.Entities.Complex.UserModels;
using Turquoise.Exceptions;
using Turquoise.Globalization;
using Turquoise.Helpers;
using Turquoise.Web.Common.Abstract;
using Turquoise.Web.Common.Entities;
using Turquoise.Web.Common.Helpers;
using Turquoise.Web.Common.Infrastructure;
using Turquoise.Web.Common.Security;
using Turquoise.Web.Management.Models;

namespace Turquoise.Web.Management.Controllers.Pages.User
{
    public class UserController : TurquoiseController
    {
        private readonly ISettingService _settingService;
        private readonly ILanguageService _languageService;
        private readonly ISessionService _sessionService;
        private readonly IUserService _userService;
        private readonly IWebSecurityManager _webSecurityManager;

        public UserController(ISessionService sessionService, IWebSecurityManager webSecurityManager, ISettingService settingService, ILanguageService languageService, IUserService userService)
        {
            _sessionService = sessionService;
            _webSecurityManager = webSecurityManager;
            _settingService = settingService;
            _languageService = languageService;
            _userService = userService;
        }

        public ViewResult Login()
        {
            var model = _sessionService.Login();
            return View(model);
        }

        [TurquoiseSecurity]
        public ViewResult MyAccount()
        {
            return View(_userService.MyAccount());
        }

        public ViewResult Header()
        {
            var account = _userService.MyAccount();
            var model = new HeaderModel
            {
                Languages = _languageService.GetAll(),
                LastLoginTime = account.LastLoginTime,
                RemainingSessionTime = account.RemainingSessionTime,
                ApplicationName = _settingService.GetValueByKey("ApplicationName")
            };
            return View(model);
        }

        public ViewResult UserSidebar()
        {
            return View(_userService.MyAccount());
        }

        [HttpPost]
        public ActionResult Login(LoginModel model)
        {
            try
            {
                CaptchaHelper.SetCaptcha(model);
                if (CaptchaHelper.HasError)
                {
                    ModelState.AddModelError("CaptchaValue", CaptchaHelper.ErrorMessage);
                    return View(model);
                }

                _sessionService.Login(model);
                _webSecurityManager.Set(ControllerIdentity, DateTime.Now.AddMinutes(_settingService.GetValueByKey("SessionTimeOut").ConvertToInt()), WebConstants.PrivateKey, ControllerIdentity.RememberMe);

                var principal = (TurquoisePrincipal)Thread.CurrentPrincipal;
                System.Web.HttpContext.Current.User = principal;

                TempData["RedirectionModel"] = new RedirectionModel
                {
                    Message = Resources.LoginSuccessMessage,
                    CssClass = "alert alert-success",
                    Timeout = 2,
                    Url = "/" + ControllerIdentity.LanguageCode + "/User/MyAccount"
                };

                return RedirectToAction("Redirect", "Redirection");
            }

            catch (ValidationException exception)
            {
                var validationResult = exception.ValidationResult;
                foreach (var t in validationResult)
                {
                    ModelState.AddModelError(t.PropertyName, t.ErrorMessage);
                }
            }

            catch (Exception exception)
            {
                model.Message = exception.Message;
            }

            finally
            {
                model.Languages = _languageService.GetAll();
            }

            return View(model);

        }

        public ViewResult ForgotPassword()
        {
            var model = _userService.ForgotPassword();
            return View(model);
        }

        [HttpPost]
        public ActionResult ForgotPassword(UpdateModel model)
        {
            try
            {
                CaptchaHelper.SetCaptcha(model);
                if (CaptchaHelper.HasError)
                {
                    ModelState.AddModelError("CaptchaValue", CaptchaHelper.ErrorMessage);
                    return View(model);
                }
                _userService.ForgotPassword(model);

                TempData["RedirectionModel"] = new RedirectionModel
                {
                    Message = Resources.ForgotPasswordMessage,
                    CssClass = "alert alert-success",
                    Timeout = 2,
                    Url = "/"
                };

                return RedirectToAction("Redirect", "Redirection");


            }

            catch (ValidationException exception)
            {
                var validationResult = exception.ValidationResult;
                foreach (var t in validationResult)
                {
                    ModelState.AddModelError(t.PropertyName, t.ErrorMessage);
                }
            }

            catch (Exception exception)
            {
                model.Message = exception.Message;
            }

            finally
            {
                model.Languages = _languageService.GetAll();
            }

            return View(model);
        }

        public ViewResult SignUp()
        {
            var model = _userService.SignUp();
            return View(model);
        }

        [HttpPost]
        public ActionResult SignUp(AddModel model)
        {
            model.Languages = _languageService.GetAll();
            try
            {
                CaptchaHelper.SetCaptcha(model);
                if (CaptchaHelper.HasError)
                {
                    ModelState.AddModelError("CaptchaValue", CaptchaHelper.ErrorMessage);
                    return View(model);
                }
                _userService.SignUp(model);

                TempData["RedirectionModel"] = new RedirectionModel
                {
                    Message = Resources.ForgotPasswordMessage,
                    CssClass = "alert alert-success",
                    Timeout = 2,
                    Url = "/"
                };

                return RedirectToAction("Redirect", "Redirection");


            }
            catch (ValidationException exception)
            {
                var validationResult = exception.ValidationResult;
                foreach (var t in validationResult)
                {
                    ModelState.AddModelError(t.PropertyName, t.ErrorMessage);
                }
            }

            catch (Exception exception)
            {
                model.Message = exception.Message;
            }
            return View(model);
        }

        [TurquoiseSecurity]
        public ViewResult UpdateMyPassword()
        {
            var model = _userService.UpdateMyPassword();
            return View(model);
        }

        [TurquoiseSecurity]
        [HttpPost]
        public ActionResult UpdateMyPassword(UpdateModel model)
        {
            try
            {
                _userService.UpdateMyPassword(model);
                TempData["RedirectionModel"] = new RedirectionModel
                {
                    Message = Resources.UpdateMyPasswordSuccessMessage,
                    CssClass = "alert alert-success",
                    Timeout = 2,
                    Url = "/" + ControllerIdentity.LanguageCode + "/User/MyAccount"
                };
                return RedirectToAction("Redirect", "Redirection");
            }
            catch (ValidationException exception)
            {
                foreach (var t in exception.ValidationResult)
                {
                    ModelState.AddModelError(t.PropertyName, t.ErrorMessage);
                }
            }
            catch (Exception exception)
            {
                model.Message = exception.Message;
            }
            return View(model);
        }

        [TurquoiseSecurity]
        public ViewResult UpdateMyInformation()
        {
            var model = _userService.UpdateMyInformation();
            return View(model);
        }

        [TurquoiseSecurity]
        [HttpPost]
        public ActionResult UpdateMyInformation(UpdateModel model)
        {
            model.Languages = _languageService.GetAll();
            try
            {
                _userService.UpdateMyInformation(model);
                TempData["RedirectionModel"] = new RedirectionModel
                {
                    Message = Resources.UpdateMyInformationSuccessMessage,
                    CssClass = "alert alert-success",
                    Timeout = 2,
                    Url = "/" + ControllerIdentity.LanguageCode + "/User/MyAccount"
                };

                return RedirectToAction("Redirect", "Redirection");



            }
            catch (ValidationException exception)
            {
                foreach (var t in exception.ValidationResult)
                {
                    ModelState.AddModelError("User." + t.PropertyName, t.ErrorMessage);
                }
            }
            catch (Exception exception)
            {
                model.Message = exception.Message;
            }
            return View(model);
        }

        public ActionResult Logout()
        {
            _sessionService.Logout(LogoutOptions.ValidLogut);
            _webSecurityManager.Remove(WebConstants.PrivateKey);
            var principle = (TurquoisePrincipal)Thread.CurrentPrincipal;
            HttpContext.User = principle;
            TempData["RedirectionModel"] = new RedirectionModel
            {
                Message = Resources.Logout,
                CssClass = "alert alert-success",
                Timeout = 2,
                Url = "/"
            };
            return RedirectToAction("Redirect", "Redirection");
        }

        public ActionResult TimeOutLogout()
        {
            _sessionService.Logout(LogoutOptions.TimeOut);
            TempData["RedirectionModel"] = new RedirectionModel
            {
                Message = Resources.SessionTimeOutMessage,
                CssClass = "alert alert-danger",
                Timeout = 2,
                Url = "/" + ControllerIdentity.LanguageCode + "/User/Login"
            };
            return RedirectToAction("Redirect", "Redirection");

        }
    }
}